package org.tehon.am;

import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.zxing.client.android.CaptureActivity;

import java.net.*;

public class MainActivity extends Activity {

    private static final int SCAN_CODE = 1;    // 扫描代码常量
    private static String SRV_IP;              // 被控端IP
    private static int SRV_PORT;               // 被控端端口
    private static int X, BASE_X = 0;          // X方向增量，基准姿态X值
    private static int Y, BASE_Y = 0;          // Y方向增量，基准姿态Y值
    private static boolean ING = false;        // 是否在监听状态
    private static boolean TOUCH = false;      // 是否按住状态，用于消息事件解耦

    private SensorManager sensorManager;
    private PosListener sensorEventListener;
    private InetAddress server;
    private DatagramSocket socket;
    private InformationCenter ic;
    private ImageView scanBtn, pauseBtn, leftBtn, rightBtn;
    private ImageView firstBtn, lastBtn, whiteBtn, blackBtn, f5Btn, escBtn, upBtn, downBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 检查无线网络
        chkWifi();

        // 防止应用使用期间手机自动锁屏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        Button baseBtn = (Button)findViewById(R.id.base);
        baseBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BASE_X = X;
                BASE_Y = Y;
            }
        });

        Button resetBtn = (Button)findViewById(R.id.def);
        resetBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BASE_X = 0;
                BASE_Y = 0;
            }
        });

        scanBtn = (ImageView)findViewById(R.id.scan);
        scanBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                startActivityForResult(intent, SCAN_CODE);
            }
        });

        pauseBtn = (ImageView)findViewById(R.id.ctrl);
        pauseBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(ING) {
                    ING = false;
                    unregSensor();
                    pauseBtn.setImageResource(R.drawable.circle_play);
                } else {
                    ING = true;
                    regSensor();
                    pauseBtn.setImageResource(R.drawable.circle_pause);
                }
            }
        });

        f5Btn = (ImageView)findViewById(R.id.f5);
        f5Btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,F");
            }
        });

        escBtn = (ImageView)findViewById(R.id.esc);
        escBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,Q");
            }
        });

        upBtn = (ImageView)findViewById(R.id.up);
        upBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,P");
            }
        });

        downBtn = (ImageView)findViewById(R.id.down);
        downBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,N");
            }
        });

        firstBtn = (ImageView)findViewById(R.id.begin);
        firstBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,H");
            }
        });

        lastBtn = (ImageView)findViewById(R.id.end);
        lastBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,E");
            }
        });

        whiteBtn = (ImageView)findViewById(R.id.white);
        whiteBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,W");
            }
        });

        blackBtn = (ImageView)findViewById(R.id.black);
        blackBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("2,B");
            }
        });

        leftBtn = (ImageView)findViewById(R.id.left);
        leftBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(TOUCH) {
                    TOUCH = false;
                } else {
                    send("1,8");
                }
            }
        });
        leftBtn.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                TOUCH = true;
                return false;
            }
        });
        leftBtn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(event.getAction() == MotionEvent.ACTION_DOWN) {
                    send("1,1");
                } else if(event.getAction() == MotionEvent.ACTION_UP) {
                    send("1,0");
                }
                return false;
            }
        });

        rightBtn = (ImageView)findViewById(R.id.right);
        rightBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send("1,2");
            }
        });
    }

    /**
     * 扫码结束后的处理
     * @param requestCode 请求码
     * @param resultCode 结果码
     * @param data 取得的数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == SCAN_CODE) {
            if (resultCode == RESULT_OK) {
                // 开始传感器监听
                sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
                sensorEventListener = new PosListener();

                // 建立网络连接
                String[] srvCtrl = data.getStringExtra("scan_result").split(",");
                SRV_IP = srvCtrl[0];
                SRV_PORT = Integer.valueOf(srvCtrl[1]);
                try {
                    server = InetAddress.getByName(SRV_IP);
                    socket = new DatagramSocket(SRV_PORT);
                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(this, "网络连接异常，程序退出。", Toast.LENGTH_SHORT).show();
                    finish();
                }

                // 界面控制可用化
                enableButtons();
                pauseBtn.setImageResource(R.drawable.circle_pause);
                ING = true;

                // 消息处理线程启动
                ic = new InformationCenter();
                regSensor();

                // 告知被控端界面最小化到托盘
                send("3,B");
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "扫描取消。", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * 暂停监听传感器
     */
    public void unregSensor() {
        if(sensorManager != null && sensorEventListener != null)
            sensorManager.unregisterListener(sensorEventListener);
    }

    /**
     * 恢复监听传感器
     */
    public void regSensor() {
        sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_NORMAL);
        new Thread(ic).start();
    }

    /**
     * 将界面按钮全部可点击化
     */
    public void enableButtons() {
        scanBtn.setClickable(true);
        pauseBtn.setClickable(true);
        f5Btn.setClickable(true);
        escBtn.setClickable(true);
        upBtn.setClickable(true);
        downBtn.setClickable(true);
        firstBtn.setClickable(true);
        lastBtn.setClickable(true);
        whiteBtn.setClickable(true);
        blackBtn.setClickable(true);
        leftBtn.setClickable(true);
        rightBtn.setClickable(true);
    }

    /**
     * 发出非姿态类指令
     * @param instruction 指令字符串
     */
    public void send(final String instruction) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    byte[] buf;
                    buf = instruction.getBytes();
                    socket.send(new DatagramPacket(buf, buf.length, server, SRV_PORT));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 检查WiFi是否打开，未打开则打开并提示
     * @return 调用时是否打开
     */
    public void chkWifi() {
        WifiManager wifiManager = (WifiManager)getSystemService(Service.WIFI_SERVICE);
        int wifi = wifiManager.getWifiState();
        if(wifi != 3) {
            wifiManager.setWifiEnabled(true);
            Toast.makeText(this, "请连接到AirMouse热点。", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 退出时注销各类资源
     */
    @Override
    protected void onStop() {
        ING = false;
        unregSensor();
        super.onStop();
    }

    /**
     * 向被控端发送姿态信息的消息处理线程类
     */
    class InformationCenter implements Runnable {

        @Override
        public void run() {
            try{
                byte[] buf;
                // 监听时工作，监听停止后死亡
                while(ING) {
                    buf = ("0," + (X - BASE_X) + "," + (Y - BASE_Y)).getBytes();
                    socket.send(new DatagramPacket(buf, buf.length, server, SRV_PORT));
                    Thread.sleep(10);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 手机姿态监听类，当姿态改变时设定新的全局XY值
     */
    final class PosListener implements SensorEventListener {

        @Override
        public void onSensorChanged(SensorEvent event) {
            if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                X = Math.round(event.values[SensorManager.DATA_X]);
                Y = Math.round(event.values[SensorManager.DATA_Y]);
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    }

}
